﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

using Buddy.BehaviorTree;
using Buddy.CommonBot;
using Buddy.CommonBot.Logic;
using Buddy.Swtor;
using Buddy.Swtor.Objects;

using WingIt;
using WingIt.Dynamics;
using WingIt.Routines.Mirrors;

namespace WingIt.Routines
{
    [RevisionControlId("$Id: AgentSmugglerBasic.cs 686 2012-08-12 16:12:20Z Chinajade $")]
    public class AgentSmuggler : MirrorRoutine
    {
        // MAINTAINERS NOTES:
        // * You will notice that lambda expression argument names are unique (e.g., "darkWardOn", "darkWardWhen", "joltWhen"),
        //   instead of generic (e.g., "ctx", "ret", "on", "doWhen", "castWhen").  PLEASE honor this convention!
        //   This allows us to quickly localize problems when looking at user's logs.  When the BehaviorTree encounters an exception
        //   (e.g., "object not found"), the location where an exception is thrown is identifiable only through the name
        //   of the lambda expression argument.  Such is the nature of BehaviorTrees.

        [Behavior(BehaviorType.Pull)]
        [Class(CharacterClass.Agent)]
        [Class(CharacterClass.Agent, AdvancedClass.Operative, SkillTreeId.None)]
        [Class(CharacterClass.Agent, AdvancedClass.Sniper, SkillTreeId.None)]
        [Class(CharacterClass.Smuggler)]
        [Class(CharacterClass.Smuggler, AdvancedClass.Scoundrel, SkillTreeId.None)]
        [Class(CharacterClass.Smuggler, AdvancedClass.Gunslinger, SkillTreeId.None)]
        public static Composite AgentSmuggler_Pull()
        {
            return new PrioritySelector(
                LazyRaider.CreateBTPS_NotifyAndShortCircuitWhenCombatDisabled(),
                CreateBTPS.BWcoreFixup_WaitForHarvestComplete(),
                TargetSelect.CreateBTPS_UpdateForBattlefieldConditions(),

                CreateBTPS.MoveAndCoverForTarget(target => MyTarget),
                Cast("Fragmentation Grenade", fragmentationGrenadeWhen => MyTarget.MobCountAround(Global.Distance.MeleeAoE) >= 3 && Resource >= 67),
                Cast("Snipe", snipeWhen => Me.IsInCover() && (Resource >= 67) && (MyTarget.HealthPercent > 20)),
                Cast("Rifle Shot")
                );
        }
        
        [Behavior(BehaviorType.Combat)]
        [Class(CharacterClass.Agent)]
        [Class(CharacterClass.Agent, AdvancedClass.Operative, SkillTreeId.None)]
        [Class(CharacterClass.Agent, AdvancedClass.Sniper, SkillTreeId.None)]
        [Class(CharacterClass.Smuggler)]
        [Class(CharacterClass.Smuggler, AdvancedClass.Scoundrel, SkillTreeId.None)]
        [Class(CharacterClass.Smuggler, AdvancedClass.Gunslinger, SkillTreeId.None)]
        public static Composite AgentSmuggler_Combat()
        {
            //Neo93 29.04.2012
            return new PrioritySelector(
                LazyRaider.CreateBTPS_NotifyAndShortCircuitWhenCombatDisabled(),
                TargetSelect.CreateBTPS_UpdateForBattlefieldConditions(),

                //***General***
                BuffSelf("Escape", escapeWhen => Me.IsStunned),//CC Break
                CreateBTPS.MoveAndCoverForTarget(myTarget => MyTarget),

                // CC
                Cast("Flash Bang", flashBangWhen => MyTarget.MobCountAround(Global.Distance.MeleeAoE) >= 3),

                // Offensive
                Cast("Explosive Probe", explosiveProbeWhen => Me.IsInCover() && Resource >= 67),
                Cast("Fragmentation Grenade", fragmentationGrenadeWhen => MyTarget.MobCountAround(Global.Distance.MeleeAoE) >= 3 && Resource >= 67),// Thermal Granade
                Cast("Debilitate", debilitateWhen => MyTarget.IsInRange(0.4f) && Resource >= 70),//Stun 
                Cast("Overload Shot", overloadShotWhen => Resource >= 67 && MyTarget.IsInRange(1f)),//Nice dmg shot
                Cast("Corrosive Dart", corrosiveDartWhen => Global.RequiresCrowdControl && !MyTarget.HasMirrorDebuff("Poisoned (Tech)")), // Vital Shot ( Bleeding (Tech) )
                Cast("Snipe", snipeWhen => Me.IsInCover() && (Resource >= 67) && (MyTarget.HealthPercent > 20)),
                Cast("Shiv", shivWhen => MyTarget.IsInRange(Global.Distance.Melee) && Resource >= 67),//melee attack
                Cast("Rifle Shot", rifleShotWhen => Resource <= 60 || ((MyTarget.Toughness == CombatToughness.Standard || MyTarget.Toughness == CombatToughness.Weak) &&
                                                                           MyTarget.HealthPercent <= 20)),//No Resource needed

                // Last resort attack, if cover fails for some reason, or other ugly things happen --
                // Last resort attacks should be 'unqualified' with a castWhen.
                Cast("Fragmentation Grenade"),
                Cast("Rifle Shot")
                );
        }

        [Behavior(BehaviorType.OutOfCombat)]
        [Class(CharacterClass.Agent)]
        [Class(CharacterClass.Agent, AdvancedClass.Operative, SkillTreeId.None)]
        [Class(CharacterClass.Agent, AdvancedClass.Sniper, SkillTreeId.None)]
        [Class(CharacterClass.Smuggler)]
        [Class(CharacterClass.Smuggler, AdvancedClass.Scoundrel, SkillTreeId.None)]
        [Class(CharacterClass.Smuggler, AdvancedClass.Gunslinger, SkillTreeId.None)]
        public static Composite AgentSmuggler_OutOfCombat()
        {
            // NB: Apparently, BWcore will call this routine when in combat on occasion.  It is also called while we're pulling.
            return (new PrioritySelector(
                TargetSelect.CreateBTPS_UpdateForBattlefieldConditions(),
                new Decorator(whenOoc => !Me.IsMounted,
                    new PrioritySelector(
                        // Only break cover when we're not in pull...
                        new Decorator(breakCoverWhen => !Me.InCombat && !TargetSelect.IsAtThePull(),
                            CreateBTPS.BreakCrouchOrCover())     // Prevents the 'stuck handler dance' if combat ends in crouch/cover
                        ))
                ));
        }
    }
}
